{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6ad55011",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'Name': 'Ford Prefect', 'Gender': 'Male', 'Occupation': 'Researcher', 'Home Planet': 'Betelgeuse Seven'}\n",
      "Male\n",
      "{'Name': 'Ford Prefect', 'Gender': 'Male', 'Occupation': 'Researcher', 'Home Planet': 'Betelgeuse Seven', 'Age': 30}\n",
      "{'a': 0, 'e': 0, 'i': 0, 'o': 0, 'u': 0}\n",
      "{'a': 0, 'e': 1, 'i': 0, 'o': 0, 'u': 0}\n",
      "{'a': 0, 'e': 2, 'i': 0, 'o': 0, 'u': 0}\n",
      "a 出现了 0 次\n",
      "e 出现了 2 次\n",
      "i 出现了 0 次\n",
      "o 出现了 0 次\n",
      "u 出现了 0 次\n",
      "a 出现了 0 次\n",
      "e 出现了 2 次\n",
      "i 出现了 0 次\n",
      "o 出现了 0 次\n",
      "u 出现了 0 次\n",
      "a 出现了 0 次\n",
      "e 出现了 2 次\n",
      "i 出现了 0 次\n",
      "o 出现了 0 次\n",
      "u 出现了 0 次\n"
     ]
    }
   ],
   "source": [
    "# 字典  （存储键/值对——用来保存键值对的集合）---用来存储数据\n",
    "# 字典模型：两行数据，多个数据行（每个唯一的键有一个与之相关联的值）\n",
    "# 以下为字典  1.字典要用{}包围  2.键和值之间用 : 隔开，每个键值对用 , 隔开；左边为键右边为值（相当于左列为键右列为值） 3. 书写时要把每组键值对换行写（如下）这样更易读  4.键和值不一定是字符串\n",
    "person3 = {'Name':'Ford Prefect',\n",
    "           'Gender':'Male',\n",
    "           'Occupation':'Researcher',\n",
    "           'Home Planet':'Betelgeuse Seven'}\n",
    "print(person3)  # 运行的结果不会按照输入字典中的顺序排列  --> 字典是无序排列的集合\n",
    "# 字典中取某个值是靠键来找的\n",
    "print(person3['Gender'])  # 运行的结果为：Male\n",
    "# 在字典中增加新的键值对（扩展） 用法：dict[要增加的键] = 要增加的值\n",
    "person3['Age'] = 30\n",
    "print(person3)\n",
    "# 统计频度数\n",
    "found = {}        # 创建一个空字典\n",
    "found['a'] = 0    # 接下来向空字典中添加键值对\n",
    "found['e'] = 0\n",
    "found['i'] = 0\n",
    "found['o'] = 0\n",
    "found['u'] = 0\n",
    "# 关联的值初始化都为0，表示还未找到任何元音字母\n",
    "print(found)  # {'a': 0, 'e': 0, 'i': 0, 'o': 0, 'u': 0}\n",
    "# 开始递增数\n",
    "found['e'] = found['e'] + 1  # 增加e的计数\n",
    "print(found)  # {'a': 0, 'e': 1, 'i': 0, 'o': 0, 'u': 0}\n",
    "# 简化赋值操作符“+=”\n",
    "found['e'] += 1  # 用 += 1这样可以使原来的对象加上1  赋值操作时都可以这样做用（+=）\n",
    "print(found)  # {'a': 0, 'e': 2, 'i': 0, 'o': 0, 'u': 0} 这是在上面的基础上对e再递增计数1 所以此时e=2\n",
    "# 利用for循环 统计频数\n",
    "for k in found:  # 用for循环在found中循环迭代找出所有的键值对，并把找出的键值对赋给一个新变量 k\n",
    "    print(k,\"出现了\",found[k],\"次\")  # k是键 found[k] 表示对应k的值\n",
    "# 由于字典是无序的集合 每次输出的结果都是乱序的 如果想让字典输出的结果为我们在输入字典中的对象顺序一样的话 需要用到 sorted函数 用法：sorted(字典名)\n",
    "for k in sorted(found):\n",
    "    print(k, \"出现了\", found[k], \"次\")\n",
    "# 在for循环中使用items函数（ items()用于返回多个值 <所以在和for使用的时候一定要有2个及以上的变量> 在字典中使用可以返回一个键值对表）\n",
    "# 在这里k,e是循环变量 用来访问字典中的键和值  注：每当想要按特定的顺序迭代处理键值对时都要使用sorted\n",
    "for k,e in sorted(found.items()):\n",
    "    print(k, \"出现了\", found[k], \"次\")\n",
    "\n",
    "# 项目练习——在给出的单词中找到元音字母并计算每个元音字母出现的次数\n",
    "vowels = [\"a\",\"e\",\"i\",\"o\",\"u\"]\n",
    "word = input(\"请输入你想要查询的词组:\")\n",
    "found = {}        # 创建一个空字典\n",
    "found['a'] = 0    # 关联值都初始话为0\n",
    "found['e'] = 0\n",
    "found['i'] = 0\n",
    "found['o'] = 0\n",
    "found['u'] = 0\n",
    "for letter in word:   # 用for循环取出用户输入的单词的所有字母\n",
    "    if letter in vowels:  # 判断 单词的字母是否有在元音字母表中\n",
    "        found[letter] += 1   # 如果有 则letter对应的元音字母的值（出现的次数）增加1（每出现一次就加1）\n",
    "for k,v in found.items():  # items可以调出每次访问的数据行即一个键值对\n",
    "    print(k, \"出现了\", v, \"次\")              # 注意！！！该代码块中有两个for循环(为同级关系注意缩进) 执行的时候只有前面的for循环结束才会轮到后面的for循环\n",
    "# 以上代码返回的结果包含了词组未出现的元音字母的次数为0\n",
    "\n",
    "# 用in来判断字典中是否存在某个键 再根据键来找到对应的值\n",
    "fruits = {}\n",
    "fruits['apples'] = 10\n",
    "print(fruits)  # {'apples': 10}\n",
    "print('apples' in fruits)  # True 说明in同样也可以用于字典的查询，当存在的时候会返回True值 不存在的是时候就会返回False\n",
    "if 'bananas' in fruits:  # 用if语句和in判断来确定bananas是否在字典fruits中\n",
    "    fruits['bananas'] += 1   # 如果字典中已经存在bananas则它值就增加1\n",
    "else:\n",
    "    fruits['bananas'] = 1   # 如果不存在就将bananas加到字典中且它对应的值初始化为1\n",
    "    print(fruits)     # {'apples': 10, 'bananas': 1}  出现这个值是由于在in查询的时候找不到键为bananas所以返回False 这样就执行了else中的代码组\n",
    "\n",
    "# 以下的情况为值已经存在直接加1\n",
    "# fruits = {'apples': 10,'bananas': 1}\n",
    "# if 'apples' in fruits:\n",
    "#     fruits['apples'] += 1\n",
    "# else:\n",
    "#     fruits['apples'] = 1\n",
    "#     print(fruits)   # {'apples': 11, 'bananas': 1}\n",
    "\n",
    "# 用not in来查询\n",
    "fruits = {}\n",
    "fruits['apples'] = 10\n",
    "if 'prease' not in fruits:   # not in判断是否在字典中 不在则返False\n",
    "    fruits['prease'] = 0   # 如果prease不存在字典中 则先使其值初始化为0（可以看成是把prease加到里面赋予值为0）\n",
    "    fruits['prease'] += 1   # 用了not in 就不需要else   这里直接使prease的值加1  （这里就相当于在字典中对prease的值加1）\n",
    "    print(fruits)   # {'apples': 10, 'prease': 1}\n",
    "\n",
    "# 用setdefault函数的方法来代替判断if语句   setdefault 可以把一个不存在的键初始化为一个指定的默认值\n",
    "fruits.setdefault('prease',0)\n",
    "fruits['prease'] += 1\n",
    "print(fruits)    # {'apples': 10, 'prease': 2}  这里没什么变化的原因是由于prease已经存储在字典中所以再用setdefault方法是没有作用的\n",
    "\n",
    "# 课本项目练习\n",
    "vowels = [\"a\",\"e\",\"i\",\"o\",\"u\"]\n",
    "word = input(\"请输入你想要查询的词组:\")\n",
    "found = {}\n",
    "for letter in word:\n",
    "    if letter in vowels:\n",
    "        found.setdefault(letter,0)\n",
    "        found[letter] += 1\n",
    "for k,v in found.items():\n",
    "    print(k, \"出现了\", v, \"次\")\n",
    "# 这块代码就实现了 不会出现出现0次的结果（如果为0次 就不用告诉了）\n",
    "\n",
    "\n",
    "# 集合 —— 无序的唯一的对象集合\n",
    "# 1. 集合的对象用{}包起来，对象之间用 , 隔开  2.集合中绝对没有重复值 且集合里的对象没有顺序\n",
    "vowels = {'a','e','i','o','u','o','a'}\n",
    "print(vowels)    # {'a', 'e', 'u', 'i', 'o'} 集合中会把重复值删去 顺序也不同了\n",
    "# 集合的快速写法\n",
    "volwes1 = set('aeiouueei')  # 变量名 = set(对象)  向set传递任意的序列 这个序列中的对象将被创建为一个没有重复值的集合\n",
    "print(volwes1)  # {'e', 'o', 'a', 'i', 'u'}\n",
    "# 并集\n",
    "# union函数 把两个结合合并到一个新的集合里面 ，原来的两个集合不会变\n",
    "vowels2 = set('aeiou')  # 先建立一个集合\n",
    "word = 'python'   # 给变量word赋予一个字符串\n",
    "u = vowels2.union(set(word)) # set（word）：先把word值转换为一个字母集合  再对刚刚建立的第一个集合vowels2调用union方法 把第二个集合合并到第一个集合中去，并将新的集合赋给一个新的变量u\n",
    "print(u)   # {'h', 'n', 'u', 'o', 'p', 'a', 'i', 'e', 'y', 't'}\n",
    "# 集合合并之后还是一个集合 也就是说这里的u本质还是一个集合  并集里也没有重复值，即使两个原集合有互相重复的值 再合并后就会被删除\n",
    "\n",
    "# 将集合转换为一个有序的列表\n",
    "u_list = sorted(list(u))   # 用list把变量u的值转化为一个列表 并用sorted函数使其有序（会按照26字母表排序）\n",
    "print(u_list)    # ['a', 'e', 'h', 'i', 'n', 'o', 'p', 't', 'u', 'y']\n",
    "\n",
    "# 差集\n",
    "# difference函数 用来对比两个集合 并将不同的元素挑出形成新的集合\n",
    "vowels2 = set('aeiou')\n",
    "word = 'python'\n",
    "d = vowels2.difference(set(word))  # 表示将word集合和vowels2集合进行对比，把vowles2中有而word中没有的字母形成一个新的集合\n",
    "print(d)  # {'e', 'i', 'a', 'u'}   （可以看成集合的等式为 vowels2-word=d）\n",
    "\n",
    "# 交集\n",
    "# intersection 函数 用来把两个集合共有的对象形成新的集合\n",
    "vowels2 = set('aeiou')\n",
    "word = 'python'\n",
    "i = vowels2.intersection(set(word))\n",
    "print(i)  # {'o'}\n",
    "\n",
    "# 课本项目练习\n",
    "vowels = set('aeiou')\n",
    "word = input(\"请输入一个想要查询的单词：\")\n",
    "found = vowels.intersection(set(word))   # 用集合中的交集的方法就可以把word中含有的元音字母没有重复的找出来\n",
    "for a in found:\n",
    "    print(a)\n",
    "\n",
    "\n",
    "# 元组 —— 有序不可变对象集合\n",
    "# 1. 元组内的对象是用（）包起来 每个对象之间用 , 隔开   2.元组是不可变的且有顺序的\n",
    "vowels3 = ('a','e','i','o','u')\n",
    "print(vowels3)  # ('a', 'e', 'i', 'o', 'u') 这是有顺序的\n",
    "# 辨别元组\n",
    "t1 = ('python')   # 这是一个只有一个对象的元组（其实不是）\n",
    "print(t1)    # 结果是一个字符串\n",
    "print()\n",
    "t2 = ('python',)  # 当只有一个对象的元组时，（）内至少要有一个逗号 才能表示为元组\n",
    "print(t2)   # ('python',)  这样就是一个元组\n",
    "\n",
    "\n",
    "# 字典的嵌套\n",
    "import pprint   # 使用pprint模块（美观打印）可以打印出美观的字典\n",
    "people = {}    # 先创建一个空的字典（相当于是最大的那个容器）\n",
    "people['Ford'] = {\"Name\":'Ford Prefect',               #  Ford是键 后面{}内是与键相关的值 此时这个值为另外一个字典\n",
    "                  \"Gender\":'Male',                     # 以下就相当于分别把Ford Arthur Tricia Marvin 这四个键连其键对应的值一起加到people字典中，每个键对应的值都是一个字典 这样就形成了字典的嵌套\n",
    "                  \"Occupation\":'Researcher',\n",
    "                  \"Home Planet\":'Betelgeuse Seven'}\n",
    "people['Arthur'] = {\"Name\":'Arthur Dent',\n",
    "                  \"Gender\":'Male',\n",
    "                  \"Occupation\":'Sandwich-Maker',\n",
    "                  \"Home Planet\":'Earth'}\n",
    "people['Tricia'] = {\"Name\":'Tricia McMillan',\n",
    "                    \"Gender\":'Female',\n",
    "                    \"Occupation\":'Mathematician',\n",
    "                    \"Home Planet\":'Earth'}\n",
    "people['Marvin'] = {\"Name\":'Marvin',\n",
    "                    \"Gender\":'Unknown',\n",
    "                    \"Occupation\":'Paranoid Android',\n",
    "                    \"Home Planet\":'Unknown'}\n",
    "# print(people)  # 此时打印出来的结果是很难读的嵌套字典\n",
    "pprint.pprint(people)\n",
    "\n",
    "# 访问上述字典中的某个具体数据——多个中括号法\n",
    "print(people['Marvin']['Home Planet'])  # Unknown"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "35f45d0b",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
